package com.gidgabs.modules.api.service.journal;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gidgabs.common.utils.Assist;
import com.gidgabs.common.utils.LangUtil;
import com.gidgabs.common.utils.PaypalUtil;
import com.gidgabs.common.utils.ReturnJson;
import com.gidgabs.config.GidgabsContants;
import com.gidgabs.dto.TbUserDto;
import com.gidgabs.dto.TbUserJournalDto;
import com.gidgabs.modules.dao.*;
import com.gidgabs.modules.entity.*;
import com.gidgabs.utils.SessionDataUtil;
import com.gidgabs.utils.UidUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 日志模块日志服务
 * Created by tby on 2018/7/6.
 */
@Service
public class JournalJournalService {
    @Autowired
    private TbUserJournalDao tbUserJournalDao;
    @Autowired private TbAliyunVideoDao tbAliyunVideoDao;
    @Autowired private PaypalUtil paypalUtil;
    @Autowired private TbUserJournalLikeDao tbUserJournalLikeDao;
    @Autowired private RedisTemplate<String,String> redisTemplate;
    @Autowired private ObjectMapper objectMapper;
    @Autowired private TbUserJournalReadDao tbUserJournalReadDao;
    @Autowired private TbUserJournalCommentDao tbUserJournalCommentDao;
    @Autowired private TbUserIncomeDao tbUserIncomeDao;
    @Autowired private TbUserDao tbUserDao;


    /**
     * 按照点赞,查看数量排序
     *
     * @param pageSize
     * @param pageNo
     * @param like
     * @return
     */
    @Transactional(readOnly = true)
    public ReturnJson<TbUserJournalDto> queryList(Integer pageSize, Integer pageNo, String like) {
        Assist assist = new Assist();
        if (StringUtils.isNotBlank(like)) {
            assist.setRequires(Assist.whereRequire("and (description like ", "%" + like + "%"),
                    Assist.whereRequire("or label like ", "%" + like + "%", ")"));
        }
        assist.setOrder(Assist.order("star_num", false),
                Assist.order("watch_num", false));

        assist.setStartRow(LangUtil.firstLimit(pageSize, pageNo)).setRowSize(pageSize);

        assist.andEq("u.delete_type",0).andEq("status",1).andIsNull("source_user_id").andEq("j.delete_type",0);
        List<TbUserJournalDto> tbUserJournalDtos = tbUserJournalDao.selectTbUserJournalLinkUser(assist);

        return ReturnJson.success("查询成功",tbUserJournalDtos);
    }

    /**
     * 发表日志
     * @param videoId
     * @param pictureUrl
     * @param description
     * @param fileName
     * @param coverURL @return
     * @param title
     * @param label
     * @param rewardMoney
     * @param rewardNum
     */
    @Transactional
    public ReturnJson createJournal(String videoId, String pictureUrl, String description, String fileName, String coverURL, String title, String label, Integer rewardMoney, Integer rewardNum) {
        TbAliyunVideoEntity tbAliyunVideoEntity=new TbAliyunVideoEntity(videoId,coverURL,description,fileName,title);
        tbAliyunVideoDao.save(tbAliyunVideoEntity);
        TbUserJournalEntity tbUserJournalEntity=new TbUserJournalEntity(SessionDataUtil.getCurrentUserId(),tbAliyunVideoEntity.getId(),pictureUrl,description,label,rewardMoney,rewardNum);
        tbUserJournalDao.insertNotNullTbUserJournal(tbUserJournalEntity);
        if (rewardMoney!=null&&rewardMoney>0){
            String payUrl = paypalUtil.pay(rewardMoney / 100d, GidgabsContants.PAYPAL_ORDER_PRE_JOURNAL + tbUserJournalEntity.getId());
            return ReturnJson.success("支付以后发表",payUrl);
        }
        return ReturnJson.success("发表成功");
    }

    @Transactional(isolation = Isolation.SERIALIZABLE)
    public ReturnJson star(Integer journalId) {
        TbUserJournalEntity journalEntity = tbUserJournalDao.getForUpdate(journalId);

        Assist assist=new Assist();
        assist.andEq("user_id_master", SessionDataUtil.getCurrentUserId()).andEq("reward_id_slave",journalId);
        List<TbUserJournalLikeEntity> tbUserJournalLikeEntities = tbUserJournalLikeDao.selectTbUserJournalLikeEntity(assist);

        if (tbUserJournalLikeEntities.size()>0){
            tbUserJournalLikeDao.deleteTbUserJournalLikeEntityByAssist(assist);
            journalEntity.setStarNum(journalEntity.getStarNum()-1);
        }else {
            TbUserJournalLikeEntity journalLikeEntity=new TbUserJournalLikeEntity(journalId,SessionDataUtil.getCurrentUserId());
            tbUserJournalLikeDao.insertNotNullTbUserJournalLikeEntity(journalLikeEntity);
            journalEntity.setStarNum(journalEntity.getStarNum()+1);
        }
        tbUserJournalDao.updateNotNullTbUserJournalById(journalEntity);
        return ReturnJson.success("操作成功");
    }

    /**
     * 日志打赏
     * @param journalId
     * @param money
     * @return
     */
    public ReturnJson reward(Integer journalId, Double money) {
        int moneyCent= (int) (money*100);
        TbUserIncomeEntity tbUserIncomeEntity=new TbUserIncomeEntity(journalId,SessionDataUtil.getCurrentUserId(),moneyCent,TbUserIncomeEntity.REVENUE_TYPE_JOURNAL_REWARD);
        String orderPayId = GidgabsContants.PAYPAL_ORDER_PRE_JOURNAL_REWARD + UidUtil.getUUID();

        try {
            String journalStr  = objectMapper.writeValueAsString(tbUserIncomeEntity);
            redisTemplate.opsForValue().set(orderPayId,journalStr);
            String payUrl = paypalUtil.pay(money, orderPayId);
            return ReturnJson.success("支付地址",payUrl);
        } catch (JsonProcessingException e) {
            return ReturnJson.fail("系统错误",e);
        }

    }

    /**
     * 获取日志详情
     * 1.增加查看数
     * 2.点赞数,查看数量
     * 3.转载数量
     * 4.评论数
     * @param journalId
     * @return
     */
    public ReturnJson<TbUserJournalDto> getById(Integer journalId) {
        Integer currentUserId = SessionDataUtil.getCurrentUserId();
        TbUserJournalEntity journalEntity = tbUserJournalDao.getForUpdate(journalId);
        if (currentUserId!=null){//增加查看记录,以及修改查看次数
            Assist assist=new Assist();
            assist.andEq("user_id_master",currentUserId).andEq("read_id_slave",journalId);
            List<TbUserJournalReadEntity> tbUserJournalReadEntities = tbUserJournalReadDao.selectTbUserJournalReadEntity(assist);
            if (tbUserJournalReadEntities.size()==0){
                TbUserJournalReadEntity tbUserJournalReadEntity=new TbUserJournalReadEntity(currentUserId,journalId);
                tbUserJournalReadDao.insertNotNullTbUserJournalReadEntity(tbUserJournalReadEntity);
                journalEntity.setWatchNum(journalEntity.getWatchNum()+1);
                tbUserJournalDao.updateNotNullTbUserJournalById(journalEntity);
            }
        }
        Assist assist = new Assist();
        assist.andEq("source_id",journalId);
        //查询转载数量
        long forwardCount = tbUserJournalDao.getTbUserJournalRowCount(assist);
        //评论数量
        assist = new Assist();
        assist.andEq("comment_id_slave",journalId);
        long commentCount = tbUserJournalCommentDao.getTbUserJournalCommentEntityRowCount(assist);
        TbAliyunVideoEntity tbAliyunVideoEntity = tbAliyunVideoDao.queryObject(journalEntity.getGidgabsVideoId());
        TbUserJournalDto tbUserJournalDto = journalEntity.toDto(tbAliyunVideoEntity);
        tbUserJournalDto.setCommentCount((int) commentCount);
        tbUserJournalDto.setForwardCount((int) forwardCount);

        //作者头像,昵称
        TbUser tbUser = tbUserDao.selectTbUserById(journalEntity.getUserId());
        tbUserJournalDto.setUserName(tbUser.getUserName());
        tbUserJournalDto.setHeadImg(tbUser.getHeadImgUrl());
        return ReturnJson.success("查询成功",tbUserJournalDto);
    }

    /**
     * 转载
     * 判断是否有转载奖励,有则生成奖励
     * @param journalId
     * @return
     */
    @Transactional(isolation = Isolation.SERIALIZABLE)
    public ReturnJson reprint(Integer journalId) {
        TbUserJournalEntity journalEntity = tbUserJournalDao.selectTbUserJournalById(journalId);
        if (journalEntity.getRewardMoney()>0&&journalEntity.getRewardNum()>0){
            Assist assist=new Assist();
            int sourceId=journalEntity.getSourceId()==null?journalEntity.getId():journalEntity.getSourceId();
            assist.andEq("source_id",sourceId);
            long reprintCount = tbUserJournalDao.getTbUserJournalRowCount(assist);
            if (reprintCount<journalEntity.getRewardNum()){
                //获得转载奖励
                int reward = journalEntity.getRewardMoney() / journalEntity.getRewardNum();
                TbUserIncomeEntity tbUserIncomeEntity=new TbUserIncomeEntity(journalId,SessionDataUtil.getCurrentUserId(),reward,TbUserIncomeEntity.REVENUE_TYPE_JOURNAL_REPRINT);
                tbUserIncomeDao.insertNotNullTbUserIncomeEntity(tbUserIncomeEntity);
            }
        }

        //转载,复制一条新的日志记录
        TbUserJournalEntity tbUserJournalEntity=journalEntity.reprint(SessionDataUtil.getCurrentUserId());
        tbUserJournalDao.insertNotNullTbUserJournal(tbUserJournalEntity);
        return ReturnJson.success("转载成功",tbUserJournalEntity);
    }
}
